-
Notifications
You must be signed in to change notification settings - Fork 716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Increase modelinefmt configuration power #1267
Conversation
Does it make the status line configurable? Can you give an example of possible configuration? |
After a good night's sleep I now conclude that this patch is a little funky, namely that it requires The workaround I can muster right now is |
@casimir It introduces two new
The latter is written with the markup that the Using these values one can to customize the modeline. The standard one is then:
(I now realize I should have documented this together with the patch.) |
That's nice! Still It needs some documentation. |
I think we would benefit from this more if all the atoms were splitted, not just spread into two sub groups. |
I am certainly willing to do that, but then I would like to make boolean values
|
Maybe there's no need to be so generic, you could make it so that each variable already contains the appropriate atom. Spawning one shell scope per atom wouldn't be very efficient, so I think there needs to be a trade off there; also the editor wasn't supposed to be 100% configurable in the first place, that's why this part of the status bar was simply rendered in one block, so a compromise has to be made to stay in line with the original idea. |
Thanks for your input @lenormf
Naturally only one is strictly needed (since
Here is a suggestion based on this then:
Also important: what about escaping values in for example |
The introduced business with escaping One way would be to have a |
I think the original separation is good enough, although I'd rename The escaping problem is tricky, and I am not really keen on passing strings around that have to be parsed down the line when we know exactly what display line we want to generate. I am not sure if there is a nice solution for that, but ideally mode_line should still return a DisplayLine, and we should not have to escape |
Updated this now. It even has documentation! I went for a solution of the escaping problem with a special markup atom Thanks all for your feedback, I hope this gets accepted. |
src/client.cc
Outdated
[](String s) { return escape(s, '{', '\\'); })); | ||
auto expanded = expand(modelinefmt, context(), ShellContext{}, | ||
[](String s) { return escape(s, '{', '\\'); }); | ||
auto m_atoms = HashMap<String, DisplayLine>{{ "mode_info", context().client().input_handler().mode_line() }}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_
is a prefix we use to mark class fields, here m_atoms
is a local variable, so it should just be named atoms
. Also, as the right hand side is not a function call, I'd rather see that written HashMap<String, DisplayLine> atoms{...};
.
src/main.cc
Outdated
@@ -154,7 +156,24 @@ void register_env_vars() | |||
"window_height", false, | |||
[](StringView name, const Context& context) -> String | |||
{ return to_string(context.window().dimensions().line); } | |||
} }; | |||
}, { | |||
"context_info", false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont think it makes much sense for that to be exposed as a value, I'd rather see it in the atoms hash map.
src/display_buffer.cc
Outdated
@@ -312,7 +317,16 @@ DisplayLine parse_display_line(StringView line) | |||
auto closing = std::find(it+1, end, '}'); | |||
if (closing == end) | |||
throw runtime_error("unclosed face definition"); | |||
face = get_face({it+1, closing}); | |||
if (*(it+1) == '`') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cant say I like this syntax, but to be faire I dont like the general display line syntax {face}
...
I think this is a good occasion to revise it, I am not sure what would be better, but I'd like to get closer to something more well known... Unfortunately none of Markdown, asciidoc, restructuredText seems to provide a syntax for face/color selection, so the remaining reference I can think of is LaTeX
but its not very satisfying either.
Any idea on what could be a nice syntax here, at least supporting changing face colors and referencing a built-in value, maybe more in the future as we'll probably want to get better formatting support for info boxes at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the javascript world, templates often use the mustache notation, so you're not too far off with the current markup.
Thank you for the review, I changed the markup to (I was under the impression that |
What does http://stackoverflow.com/questions/13018189/what-does-m-variable-prefix-mean I stumbled upon the same question while reading C++ sources. |
I remember this being a part of the google style guide for C++, back when it was first published. Must have changed since. |
src/display_buffer.cc
Outdated
@@ -312,7 +317,18 @@ DisplayLine parse_display_line(StringView line) | |||
auto closing = std::find(it+1, end, '}'); | |||
if (closing == end) | |||
throw runtime_error("unclosed face definition"); | |||
face = get_face({it+1, closing}); | |||
if (*(it+1) == '{' and *(closing+1) == '}') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
closing+1 might be the end.
src/display_buffer.cc
Outdated
return parse_display_line_with_atoms(line, HashMap<String, DisplayLine>{}); | ||
} | ||
|
||
DisplayLine parse_display_line_with_atoms(StringView line, HashMap<String, DisplayLine> atoms) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont think we need the two functions, just parse_display_line
taking a hash map argument with a defaultu value of = {}
.
src/client.cc
Outdated
@@ -124,32 +125,30 @@ DisplayLine Client::generate_mode_line() const | |||
{ | |||
const String& modelinefmt = context().options()["modelinefmt"].get<String>(); | |||
|
|||
modeline = parse_display_line(expand(modelinefmt, context(), ShellContext{}, | |||
[](String s) { return escape(s, '{', '\\'); })); | |||
String context_info = ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the context_info display line building into a helper function.
f31a464
to
5e5dd52
Compare
s += "[no-hooks]"; | ||
if (context.buffer().flags() & Buffer::Flags::Fifo) | ||
s += "[fifo]"; | ||
return s; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have just realized I don't know C++. Where is this string allocated? When will it be deleted? Is it safe to return it like this? It is sent to parse_display_line
below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The String class takes care of all that, if its small enough (<= 22 bytes), it should end up embeded in the string object, else it will end up heap allocated, but the String is taking care of the ownership of that allocation, so this code is safe.
In Kakoune code, and generally in modern style C++, these problems are solved, its only the building block classes that should take care of memory allocation/freeing and provide a safe abstraction that prevent leaks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yet another set of remarks, sorry for missing them in the first place.
src/display_buffer.cc
Outdated
@@ -286,7 +286,7 @@ void DisplayBuffer::optimize() | |||
line.optimize(); | |||
} | |||
|
|||
DisplayLine parse_display_line(StringView line) | |||
DisplayLine parse_display_line(StringView line, HashMap<String, DisplayLine> atoms) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a const HashMap<...>&
here, as we only access the map for reading, so there is no reason to copy the hash map.
src/display_buffer.cc
Outdated
face = get_face({it+1, closing}); | ||
if (*(it+1) == '{' and closing+1 != end and *(closing+1) == '}') | ||
{ | ||
auto atom_it = atoms.find(String{it+2, closing}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a StringView here, no need to copy the data.
src/display_buffer.cc
Outdated
{ | ||
auto atom_it = atoms.find(String{it+2, closing}); | ||
if (atom_it == atoms.end()) | ||
throw runtime_error(format("undefined atom {}", String{it+2, closing})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same, StringView here
src/display_buffer.cc
Outdated
auto atom_it = atoms.find(String{it+2, closing}); | ||
if (atom_it == atoms.end()) | ||
throw runtime_error(format("undefined atom {}", String{it+2, closing})); | ||
for (auto display_it = atom_it->value.begin(), end = atom_it->value.end(); display_it != end; ++display_it) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a for each, you can just write it for (auto& atom : atom_it->value) res.push_back(atom);
src/display_buffer.hh
Outdated
@@ -143,7 +144,7 @@ private: | |||
AtomList m_atoms; | |||
}; | |||
|
|||
DisplayLine parse_display_line(StringView line); | |||
DisplayLine parse_display_line(StringView line, HashMap<String, DisplayLine> m_atoms = HashMap<String, DisplayLine>{}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_atoms shoud just be atoms, and I think atom is not such a good name, I'd suggest built_ins, or named_values. Also, the default value can just be written {}
, no need to repeat the type.
No problem :) Thanks for reviewing and info about C++ 👍 ! |
Two tests need to be updated because an empty string is now on display
when %val{context_info} from modelinefmt's
{Information}%val{context_info}{default}
is empty.